/*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.gameserver.instancemanager;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.Announcements;
import com.l2jserver.gameserver.Shutdown;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;

/**
 * @author TeNaCiOuS
 */

public class AutoRestartManager
{
	private static Logger _log = Logger.getLogger(AutoRestartManager.class.getName());
	
	private static final int initialCheck = 60 * 1000;
	private static final int delayForCheck = Config.TMODS_AUTO_RESTART_CHECK_DELAY * 1000;
	private int _voteCount = 0;
	private L2PcInstance _LastPlayerVote;
	private boolean _isRestarting = false;
	private String _CurrentMethod = "";
	
	private AutoRestartManager()
	{
		_log.info("AutoRestartManager: Auto Restart System has been initiated.");
		ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new AutoRestart(), initialCheck, delayForCheck);
	}
	
	private class AutoRestart implements Runnable
	{
		
		@Override
		public void run()
		{
			if (!_isRestarting && L2World.getInstance().getAllPlayers().size() > 0)
			{
				_CurrentMethod = "";
				switch (Config.TMODS_AUTO_RESTART_TYPE)
				{
					case 1:
						if (getVoteCount() != 0 && getVoteCount() >= Config.TMODS_VOTES_NEEDED_FOR_RESTART && !_isRestarting)
						{
							Announcements.getInstance().announceToAll("Se han alcansado los votos necesarios para reiniciar el servidor.");
							_CurrentMethod = "1_ByVotesNeeded";
							saveRecord();
							_voteCount = 0;
							Shutdown.getInstance().startShutdown(_LastPlayerVote, 60, true);
							_isRestarting = true;
						}
						break;
					
					case 2:
						final float playersonline = L2World.getInstance().getAllPlayers().size();
						final float PlayersOfPercent = playersonline / 100 * Config.TMODS_PPL_PERCENT_NEEDED_FOR_RESTART;
						
						final int intpercent = Math.round(PlayersOfPercent);
						
						if (getVoteCount() != 0 && getVoteCount() >= intpercent && !_isRestarting)
						{
							Announcements.getInstance().announceToAll("El " + String.valueOf(Config.TMODS_PPL_PERCENT_NEEDED_FOR_RESTART) + "% de los jugadores ha votado a favor de reiniciar el servidor.");
							_CurrentMethod = "2_ByOnlinesPercent";
							saveRecord();
							_voteCount = 0;
							Shutdown.getInstance().startShutdown(_LastPlayerVote, 60, true);
							_isRestarting = true;
						}
						break;
					
					case 3:
						// Config.TMODS_AUTO_RESTART_TIME
						
						break;
					
					default:
						// case 1:
						if (getVoteCount() >= Config.TMODS_VOTES_NEEDED_FOR_RESTART && !_isRestarting)
						{
							Announcements.getInstance().announceToAll("Se han alcansado los votos necesarios para reiniciar el servidor.");
							_CurrentMethod = "Default_ByVotesNeeded";
							saveRecord();
							_voteCount = 0;
							Shutdown.getInstance().startShutdown(_LastPlayerVote, 60, true);
							_isRestarting = true;
						}
						break;
				}
			}
		}
	}
	
	public int getVoteCount()
	{
		return _voteCount;
	}
	
	public void increaseVoteCount(final L2PcInstance activeChar)
	{
		_voteCount = _voteCount + 1;
		_LastPlayerVote = activeChar;
	}
	
	// Fecha-Hora actual en formato timestamp	
	private static java.sql.Timestamp getCurrentTimeStamp()
	{
		final java.util.Date today = new java.util.Date();
		return new java.sql.Timestamp(today.getTime());
	}
	
	// Guarda un registro en la base de datos
	public void saveRecord()
	{
		Connection con = null;
		
		try
		{
			con = L2DatabaseFactory.getInstance().getConnection();
			final PreparedStatement statement = con.prepareStatement("INSERT INTO AutoRestartRecords (date, players_online, votes, method) VALUES (?, ?, ?, ?)");
			statement.setTimestamp(1, getCurrentTimeStamp());
			statement.setInt(2, L2World.getInstance().getAllPlayers().size());
			statement.setInt(3, _voteCount);
			statement.setString(4, _CurrentMethod);
			statement.execute();
			statement.close();
		}
		catch (final Exception e)
		{
			_log.log(Level.WARNING, "Error when try to save vote info: ", e);
		}
		finally
		{
			L2DatabaseFactory.close(con);
		}
	}
	
	public static AutoRestartManager getInstance()
	{
		return SingletonHolder._instance;
	}
	
	@SuppressWarnings("synthetic-access")
	private static class SingletonHolder
	{
		protected static final AutoRestartManager _instance = new AutoRestartManager();
	}
}
